<script setup>
import { h, ref } from 'vue';
import { message } from 'ant-design-vue';
import SpecialRoomOperation from '@/components/func/specialRoomOperation.vue';
import MapAndDraw from '@/components/map/mapAndDraw.vue';
import { DXF_LAYERS, specialRoomListCommon, TYPES } from '@/components/roomConstant/common.js';
import RoomInfoModal from '@/components/common/roomInfoModal.vue';
import { CloseOutlined, ExpandOutlined } from '@ant-design/icons-vue';
import RoomList from '@/components/common/roomList.vue';
import { printMap } from '@/utils/printMap.js';
import * as turf from "@turf/turf";
import { getFloors, getRooms, saveDXF, saveFloor, saveRoom, saveRoomByFloorId,dealRooms } from '@/api';

const props = defineProps({
  visible: {
    type: Boolean,
    default: false,
  },
  currentRowRecord: {
    type: Object,
    default: () => ({})
  },
  isImport: {
    type: Boolean,
    default: false,
  },
  parentNode: {
    type: Object,
    default: () => ({})
  }
});

const mapRef = ref();
const isEditing = ref(false);
const emits = defineEmits(['update:visible', 'save']);

const specialRoomExpression = ref();
const specialRoomTableData = ref();
const isAssign = ref(false);
const fullModalClass = ref('no-full-modal');
const dxfFileData = ref(); // 解析的dxf数据
const areaObj = reactive({
  roomArea: 0,
  buildingArea: 0
});
const provideData = reactive({
  assignSuccessData: null,
  assignFeature: {},
  currentRowData: null,
  layerColorOptions: {},
  specialRoomOptions: {
    roomUseType: [],
    roomUseUnit: []
  },
  roomInfoFeature: {},
});
const floorList = ref([]);
const currentFloor = ref();
const roomTableDataSource = ref([]);
const floorChange = async (floorId) => {
  await showRooms(floorId)
  backPreview();
}
provide('fatherData', provideData);
const showRooms = async (floorId) => {
  let floor = floorList.value.find(item => {
    if (item.id === floorId) {
      currentFloor.value = item.id;
      return true;
    }
  })
  let res = await getRooms(floorId)

  let data = {
    features: res.result.map(item => ({
      id: item.id,
      geometry: JSON.parse(item.pois),
      properties: {
        id: item.id,
        oId:item.id,
        name: item.roomName,
        area: item.constructionArea,
        layer: 'TX',
      }
    })), type: 'FeatureCollection'
  }
  const tableData = {
    id: floorId,
    name: floor.floorName,
    data: data,
    sourceData: data,
    properties: JSON.parse(floor.displaySettings),
  };
  provideData.currentRowData = tableData;
  roomTableDataHandle();
};
const sendDataWithWorker = async (data) => {
  const jsonRes = await mapRef.value.map.convert(data.file);
  const tableData = {
    id: new Date().getTime(),
    name: data.file.name,
    time: new Date().toLocaleString(),
    data: jsonRes.data,
    sourceData: jsonRes.data,
    properties: jsonRes.properties,
  };
  return tableData;
};

const initDxfLayers = async (dxfFileData) => {
  if (!dxfFileData) return;
  const hide = message.loading('正在识别，请稍后...', 0);
  const tempData = {
    data: dxfFileData.data,
    file: dxfFileData.file,
  };
  let data = await sendDataWithWorker(tempData);
  //批量新增房间
  let temp = data.data.features.map(item => {
    return {
      constructionArea: item.properties.size,
      roomName: item.properties.name,
      pois: JSON.stringify(item.geometry)
    }
  })
  saveFloor({ id: currentFloor.value, displaySettings: JSON.stringify(data.properties) }).then(res => {
    initFloors()
  })
  saveRoomByFloorId(temp, currentFloor.value).then(res => {
    if (res.code !== 200) {
      message.error('导入失败');
      return;
    } else {
      message.success('导入成功');
      showRooms(currentFloor.value);

    }
  })
  // getRoomAndPassageColor();
  // countArea();
  // roomTableDataHandle();


  // saveDxfData(provideData.currentRowData);
   importModalVisible.value = false;
  hide();
};

const setPaintPropertiesBatch = (paintProperty, value, layer = 'line') => {
  let layerArray = [];
  switch (layer) {
    case 'line':
      layerArray = ['gl-draw-lines.cold', 'gl-draw-lines.hot'];
      break;
    case 'polygon':
      layerArray = ['gl-draw-polygon-fill.cold', 'gl-draw-polygon-fill.hot'];
      break;
    default:
      break;
  }
  layerArray.forEach(layerId => {
    mapRef.value.map.instance.setPaintProperty(layerId, paintProperty, value);
  });
};

const startEdit = () => {
  mapRef.value.hidePolygonLayer();
  mapRef.value.map.instance.getCanvas().style.cursor = 'crosshair';
  isEditing.value = true;
  isAssign.value = false;
  mapRef.value.mapDraw.set(provideData.currentRowData.data);
  mapRef.value.drawOperation.cacheDrawFeature = mapRef.value.mapDraw.getAll();
  specialRoomExpression.value = null;
  setPaintPropertiesBatch('line-color',
    ['case',
      ['==', ['get', 'active'], 'true'],
      'red',
      'rgb(0, 0, 208)',
    ]);
  setPaintPropertiesBatch('line-dasharray',
    [
      'case',
      ['==', ['get', 'active'], 'true'],
      [5, 4],
      [2, 0],
    ]);
  setPaintPropertiesBatch('line-width',
    [
      'case',
      ['==', ['get', 'active'], 'true'],
      5,
      3,
    ]);
  setPaintPropertiesBatch('fill-color',
    ['case', ['has', 'user_color'], ['get', 'user_color'], 'rgba(59, 178, 208, 0.3)'],
    'polygon');
  setPaintPropertiesBatch('fill-opacity', 0.5, 'polygon');
  message.info('编辑完成后，请点击底部按钮保存~');
};

const printMapImage = async () => {
  const hide = message.loading('正在准备中，请稍后...', 0);
  // 重绘
  mapRef.value.map.instance.triggerRepaint();
  await mapRef.value.map.instance.once('idle');
  const mapCanvas = mapRef.value.map.instance.getCanvas();
  const img = document.createElement('img');
  img.src = mapCanvas.toDataURL('image/png');
  hide();
  await printMap(img);
};

const saveDxfData = (dxfGeoData) => {
  let temp = { ...dxfGeoData };
  if (typeof (temp.data) !== 'string') {
    temp.data = JSON.stringify(temp.data);
  }
  if (typeof (temp.properties) !== 'string') {
    temp.properties = JSON.stringify(temp.properties);
  }
  saveDXF(temp).then((res) => {
    if (res.code !== 200) {
      message.error('保存失败');
    } else
      message.success('保存成功');
  })

  // const dxfTable = localStorage.getItem('dxfTable');
  // let tempData = [];
  // if (dxfTable) {
  //   tempData = JSON.parse(dxfTable);
  //   const findGeoData = tempData.find((item) => item.id === dxfGeoData.id);
  //   if (findGeoData) {
  //     findGeoData.time = new Date().toLocaleString();
  //     findGeoData.data = dxfGeoData.data;
  //   } else {
  //     tempData.push(dxfGeoData);
  //   }
  // } else {
  //   tempData = [dxfGeoData];
  // }
  // try {
  //   localStorage.setItem('dxfTable', JSON.stringify(tempData));
  // } catch {
  //   message.error('保存失败，dxf文件过大');
  // }
  emits('save');
};

const countArea = () => {
  areaObj.roomArea = 0;
  areaObj.buildingArea = 0;

  provideData.currentRowData.data.features.forEach(feature => {
    if (!feature.properties.area) return;
    switch (feature.properties.layer) {
      case DXF_LAYERS.TX:
        areaObj.roomArea += parseFloat(feature.properties.area);
        break;
      case DXF_LAYERS.GG:
        areaObj.buildingArea += parseFloat(feature.properties.area);
        break;
    }
  });
  areaObj.buildingArea += areaObj.roomArea;
};

const mapModalVisible = computed({
  get() {
    return props.visible;
  },
  set(val) {
    emits('update:visible', val);
  }
});

const clickSpecialRoom = (specialRoom) => {
  mapRef.value.setDataAndStyle(['polygonLineLayer']);
  if (specialRoom.type === 'back') {
    specialRoomExpression.value = null;
    isAssign.value = false;
    return;
  }
  const colorExpression = ['case'];
  // 特殊房间
  if (specialRoom.isRoomView) {
    isAssign.value = false;
    Object.entries(specialRoom.data).forEach(([key, value]) => {
      value.count = 0;
      value.area = 0;
      colorExpression.push(
        ['==', ['get', specialRoom.type], +key],
        value.color
      );
    });
    // 默认颜色
    colorExpression.push('rgba(59, 178, 208, 0.2)');
    mapRef.value.layers[TYPES.POLYGON].options.paint['fill-color'] = colorExpression;


    provideData.currentRowData.data.features.forEach((feature) => {
      if (feature.geometry.type !== 'Polygon') return;
      const key = feature.properties[specialRoom.type];
      if (key || key === 0) {
        specialRoom.data[key].area += parseFloat(feature.properties.area);
        specialRoom.data[key].count++;
      }
    });
    specialRoomTableData.value = Object.values(specialRoom.data);
    changeCamera(true);
    specialRoomExpression.value = colorExpression;
  } else {// 分配使用人
    mapRef.value.setDataAndStyle([TYPES.POLYGON]);
    specialRoomExpression.value = null;
    isAssign.value = true;
    mapRef.value.layers['polygonLineLayer'].options.paint['line-color'] = ['case',
      ['!', ['has', 'areaMax']],
      'rgba(61,61,61,0.5)',
      ['==', ['get', 'areaMax'], true],
      'rgba(251, 11, 11,0.5)',
      'rgba(31, 243, 109,0.5)',
    ];
    mapRef.value.layers['polygonLineLayer'].options.paint['line-width'] = 3;
    changeCamera();
  }
};

const changeCamera = (isPanTo = false) => {
  const center = provideData.currentRowData?.properties?.center || 0;
  const zoom = provideData.currentRowData?.properties?.zoom || 0;
  if (isPanTo) {
    zoom && mapRef.value.map.instance.setZoom(zoom - 0.6);
    center && mapRef.value.map.instance.panTo([center[0], center[1] - 0.25], {
      duration: 500, // 动画时间（可选）
    });
  } else {
    zoom && mapRef.value.map.instance.setZoom(zoom);
    center && mapRef.value.map.instance.panTo(center, {
      duration: 500, // 动画时间（可选）
    });
  }
};

const roomTableDataHandle = () => {
  if (!provideData.currentRowData) return;
  const polygonFeature = provideData.currentRowData.data.features;
  roomTableDataSource.value = [];
  polygonFeature.forEach(polygon => {
    const tempObj = {
      name: polygon.properties.name || '',
      area: polygon.properties.area || 0,
    };
    roomTableDataSource.value.push(tempObj);
  });
};

const handleOk = async () => {
  let temp=mapRef.value.dealData
  let data={
    floorId:currentFloor.value,
    deleteRoomIds:temp.deleteRoomIds,
    saveRooms:temp.saveRooms.map(item=>({
      id:item.oId,
      pois:item.pois
    }))
  }
  let res=await dealRooms(data);
  if(res.code!==200){
    message.error('保存失败')
    return
  }else{
    message.success('保存成功')
    await showRooms(currentFloor.value)
    backPreview();
  }
  // const all = mapRef.value.mapDraw.getAll();
  // const features = all.features.filter(item => !['VERTICAL_GUIDE', 'HORIZONTAL_GUIDE'].includes(item.id));
  // provideData.currentRowData.data = turf.featureCollection(features);
  // message.success('保存成功');
  // countArea();
  // roomTableDataHandle();
  // // saveDxfData(provideData.currentRowData);
  // backPreview();
};

const handleCancel = () => {
  provideData.currentRowData = null;
  specialRoomExpression.value = null;
  mapModalVisible.value = false;
  isAssign.value = false;
  isEditing.value = false;
  emits('save');
};

const backPreview = () => {
  isEditing.value = false;
  mapRef.value.drawOperation.cacheDrawFeature = null;
};

const closeDrawer = () => {
  mapRef.value.setDataAndStyle([TYPES.POLYGON]);
  specialRoomExpression.value = null;
  changeCamera();
};

const getRoomAndPassageColor = () => {
  if (!provideData.currentRowData) return;
  const features = provideData.currentRowData.data.features;
  ['TX', 'GG'].forEach(layer => {
    const findFeature = features.find(item => item.properties.layer === layer);
    if (findFeature) {
      provideData.layerColorOptions[layer] = findFeature.properties.color;
    }
  });
};

const initSpecialRoomOption = () => {
  const specialRoomList = JSON.parse(JSON.stringify(specialRoomListCommon));
  Object.keys(specialRoomList).forEach((key) => {
    const temp = [];
    Object.entries(specialRoomList[key]).forEach(([keyItem, valueItem]) => {
      temp.push({
        label: valueItem.name,
        value: +keyItem,
      });
    });
    provideData.specialRoomOptions[key] = temp;
  });
};

const updateRoomInfo = ({ isDraw, form }) => {
  const featureCollection = isDraw ? mapRef.value.drawOperation.cacheDrawFeature : provideData.currentRowData.data;
  const featureList = featureCollection.features;
  const findFeature = featureList.find(item => item.properties.id === form.id);
  const insertFeature = [];
  findFeature.properties.currentPeople = [];
  findFeature.properties.roomUseType = form.roomUseType;
  findFeature.properties.roomUseUnit = form.roomUseUnit;
  findFeature.properties.name = form.name;
  findFeature.properties.area = form.area;

  if (form.isRoomArea) {
    findFeature.properties.layer = 'TX';
    findFeature.properties.color = provideData.layerColorOptions['TX'];
    findFeature.properties.areaList = Array.from({ length: 6 }).map(() => Math.floor(Math.random() * 31) + 1);
    findFeature.properties.areaList.push(2, 1);
    findFeature.properties.areaMax = false;
  } else {
    findFeature.properties.layer = 'GG';
    findFeature.properties.color = provideData.layerColorOptions['GG'];
    delete findFeature.properties.roomUseType;
    delete findFeature.properties.roomUseUnit;
    delete findFeature.properties.currentPeople;
    delete findFeature.properties.areaList;
    delete findFeature.properties.areaMax;
  }
  featureList.push(...insertFeature);
  if (isDraw) {
    insertFeature.forEach(item => {
      mapRef.value.mapDraw.add(item);
    });
    findTextArr.forEach(item => {
      mapRef.value.mapDraw.add(item);
    });
    mapRef.value.mapDraw.add(findFeature);
  } else {
    roomTableDataHandle();
    countArea();
    saveRoom({
      id: form.id,
      roomName: form.name,
      constructionArea: form.area,
    });
    // saveDxfData(provideData.currentRowData);
    // message.success('保存成功');
  }
  mapRef.value.map.instance.getSource(TYPES.POLYGON_TEXT).setData(featureCollection);
  mapRef.value.map.instance.getSource(TYPES.POLYGON).setData(featureCollection);
  mapRef.value.map.instance.getSource(TYPES.POLYGON_LINE).setData(featureCollection);
};

// 全屏
const floorModalFull = () => {
  fullModalClass.value = fullModalClass.value === 'full-modal' ? 'no-full-modal' : 'full-modal';
  nextTick(() => mapRef.value.map.instance.resize());
};

// // 导入的dxf数据
// watch(() => dxfFileData, (newVal) => {
//   initDxfLayers(newVal);
// });

// 是否修改
watch(isEditing, (newValue) => {
  if (!newValue) {
    mapRef.value.map.instance.getCanvas().style.cursor = '';
    mapRef.value.mapDraw.clear();
    mapRef.value.setDataAndStyle([TYPES.POLYGON, TYPES.POLYGON_LINE, TYPES.POLYGON_TEXT]);
  }
});

// 当前数据
// watch(() => props.currentRowRecord, (newValue) => {
//   if (!newValue) return;
//   if (typeof (newValue.properties) === 'string') {
//     newValue.properties = JSON.parse(newValue.properties);
//   }
//   if (typeof (newValue.data) === 'string') {
//     newValue.data = JSON.parse(newValue.data);
//   }
//   provideData.currentRowData = newValue;
//   countArea();
//   roomTableDataHandle();
//   getRoomAndPassageColor();
// });

// 显示标签
// watch(isAssign, (newValue) => {
//   isShowMarkerTag(newValue);
// });

// 分配成功
watch(() => provideData.assignSuccessData, (newValue) => {
  if (newValue) {
    // const id = newValue?.id || newValue.properties.id;
    mapRef.value.map.instance.getSource(TYPES.POLYGON).setData(provideData.currentRowData.data);
    mapRef.value.map.instance.getSource(TYPES.POLYGON_LINE).setData(provideData.currentRowData.data);
    // 设置标签
    // const findMarker = mapRef.value.markerPopup.usePeopleMarker.find(marker => marker.options.id === id);
    // if (findMarker) {
    //   findMarker.options.text = newValue.properties.currentPeople.join(',');
    // } else {
    //   const marker = mapRef.value.createMarkerPopup(newValue, true);
    //   mapRef.value.markerPopup.usePeopleMarker.push(marker);
    // }
    roomTableDataHandle();
    // saveDxfData(provideData.currentRowData);
    provideData.assignSuccessData = null;
  }
});
const initFloors = async () => {
  const res = await getFloors();
  floorList.value = res.result;
};
onMounted(() => {
  initSpecialRoomOption();
  initFloors();
});


import { InboxOutlined } from '@ant-design/icons-vue';

const importDxfFile = ref(); // 上传的文件列表
const dxfError = ref(''); // 错误信息


const importModalVisible = ref(false);
const importOk = ref(false);

const importFile = () => {
  if (currentFloor.value === undefined) {
    message.error('请选择楼层');
    return;
  }
  importModalVisible.value = true;
  importDxfFile.value = [];
};

const handleFileUpload = (info) => {
  const file = info.file;
  if (!file) return;
  const reader = new FileReader();
  reader.onload = (e) => {
    try {
      const contents = e.target.result;
      dxfFileData.value = { file, data: contents };
      initDxfLayers(dxfFileData.value)
    } catch (err) {
      dxfError.value = `解析失败: ${err.message}`;
      console.error(err);
    }
  };

  reader.onerror = () => {
    dxfError.value = '文件读取失败';
    console.error(reader.error);
  };

  reader.readAsText(file); // 以文本形式读取文件
  importOk.value = false;
};

</script>

<template>
  <div>
    <!-- <template #title>
      <div style="display: flex;justify-content: space-between">
        <div>
          {{ isEditing ? '编辑地图' : '预览地图' }}
        </div>
        <div style="display: flex;gap: 8px">
          <a-tooltip title="全屏">
            <a-button type="link" area="small" @click="floorModalFull" :icon="h(ExpandOutlined)"></a-button>
          </a-tooltip>
          <a-tooltip title="关闭">
            <a-button type="text" area="small" @click="handleCancel" :icon="h(CloseOutlined)"></a-button>
          </a-tooltip>
        </div>
      </div>

    </template> -->
    <!-- <template #footer>
      <div style="text-align: center" v-if="isEditing">
        <a-button @click="backPreview">{{ isEditing ? '返回' : '取消' }}</a-button>
        <a-button type="primary" @click="handleOk" :style="{ background: isEditing ? 'orange' : '' }">
          {{ isEditing ? '保存编辑' : '确认' }}
        </a-button>
      </div>
      <div style="height: 32px" v-else></div>
    </template> -->
    <div class="modal-container">
      <div class="map-content">
        <map-and-draw ref="mapRef" :map-expression="specialRoomExpression" :is-edit="isEditing" :is-assign="isAssign" />
        <!-- 特殊房间 -->
        <special-room-operation v-if="isImport ? false : isEditing ? false : mapModalVisible"
          @click-type="clickSpecialRoom" @close="closeDrawer" :table-data="specialRoomTableData" />
        <!-- 添加/修改房间信息 -->
        <room-info-modal @updateRoom="updateRoomInfo" />
        <div class="area-container">
          <a-select v-model:value="currentFloor" placeholder="选择楼层" :style="{ width: '100px' }" @change="floorChange">
            <a-select-option v-for="item in floorList" :key="item.id">
              {{ item.floorName }}
            </a-select-option>
          </a-select>
          <!-- <span>房间总面积：{{ areaObj.roomArea.toFixed(2) }}㎡</span>
          <span>建筑总面积：{{ areaObj.buildingArea.toFixed(2) }}㎡</span> -->
        </div>
        <div class="edit-btn">
          <a-button v-show="!isEditing" type="primary" style="background: darkcyan " @click="importFile">导入dxf
          </a-button>
          <a-button v-show="!isEditing" type="primary" style="background: orange" @click="startEdit">编辑房间
          </a-button>
          <a-button v-show="isImport ? false : !isEditing" type="primary" style="background: #74caf9"
            @click="printMapImage">打印地图
          </a-button>
        </div>
      </div>
      <!-- 房间列表 -->
      <room-list :isImport="isImport" :data-source="roomTableDataSource" :fullModalClass="fullModalClass" />
      <a-modal v-model:open="importModalVisible" title="导入文件" :footer="false">
        <a-upload-dragger accept=".dxf" v-model:file-list="importDxfFile" :max-count="1" :before-upload="() => false"
          @change="handleFileUpload">
          <p class="ant-upload-drag-icon">
            <inbox-outlined></inbox-outlined>
          </p>
          <p class="ant-upload-text">点击或者拖拽文件进行导入</p>
        </a-upload-dragger>
      </a-modal>
    </div>
    <div style="text-align: center" v-if="isEditing">
      <a-button @click="backPreview">{{ isEditing ? '返回' : '取消' }}</a-button>
      <a-button type="primary" @click="handleOk" :style="{ background: isEditing ? 'orange' : '' }">
        {{ isEditing ? '保存编辑' : '确认' }}
      </a-button>
    </div>
  </div>
</template>

<style scoped lang="scss">
.modal-container {
  width: 100%;
  height: 100%;
  display: flex;
  gap: 10px;

  .map-content {
    flex: 1;
    //width: 100%;
    //height: 100%;
    position: relative;
    border: 2px solid rgb(248, 248, 248);
    border-radius: 10px;

    .area-container {
      position: absolute;
      z-index: 1;
      top: 10px;
      left: 50%;
      transform: translateX(-50%);
      color: #606266;
      font-weight: bold;
      display: grid;
      grid-template-columns: repeat(2, 1fr);
      gap: 40px;
    }

    .edit-btn {
      position: absolute;
      top: 10px;
      right: 5px;
      z-index: 1;
      display: grid;
      gap: 10px;

      .ant-btn {
        padding: 5px 10px;
        font-area: 14px;
        display: flex;
        align-items: center;

        &:hover {
          filter: opacity(0.8);
        }
      }
    }
  }
}
</style>
